Certain server-based applications can be executed by users on one or more servers across a network. For example, rather than running individual applications (e.g., individual spreadsheet applications) on desktop computers, multiple users can access a server over an Intranet through their desktop computers and execute a server-based application (e.g., a server-based spreadsheet application) on that server. Through this server-based application, multiple users can manipulate common functionality and data available on that server.
A typical scenario might include a server-based accounting program that is accessed by multiple accountants from various enterprise departments. The server-based application receives user requests, creates and accesses data objects, performs appropriate computations on these data objects, and renders application-specific presentations of the computation results for display on the users' desktop computers (e.g., through browsers or proprietary client interfaces).
Troubleshooting errors that arise during the execution of such a server-based application is difficult. Traditionally, a software application may be tested by applying a set of inputs to the application and checking that the outputs are correct (e.g., regression testing). If the test fails, correcting the error that resulted in the failure is usually attempted by a combination of examining an application log, debugging a dump of some portions of application memory, and/or re-running the failed scenario within a debugger or with a special debug version of the software (e.g., a version compiled with run-time error detection features, such as ASSERTs, embedded in the program code).
However, these approaches become more complicated and less effective in a multi-threaded, server-based scenario supporting multiple remote users. Furthermore, while the techniques listed above may be useful, they have important limitations. For example, application logs are incremental and require an understanding of all application events occurring since the application was initiated. Memory dumps are difficult to read, lack a lot of information and context, and require substantial program knowledge and programming skills. Debugging generally requires reproduction of the failure in a different debug version of the software or on a different computing environment (e.g., on the workstation of a programmer). As such, these approaches do not adequately support troubleshooting of multi-threaded, server-based applications.